# Token types
#
# EOF (end-of-file) token is used to indicate that
# there is no more input left for lexical analysis
INTEGER, PLUS, EOF = 'INTEGER', 'PLUS', 'EOF'
 
class Token(object):
    def __init__(self, type, value):
        # token type: INTEGER, PLUS, or EOF
        self.type = type
        # token value: 0, 1, 2. 3, 4, 5, 6, 7, 8, 9, '+', or None
        self.value = value
 
    def __str__(self):
        """String representation of the class instance.
 
        Examples:
            Token(INTEGER, 3)
            Token(PLUS '+')
        """
        return 'Token({type}, {value})'.format(
            type=self.type,
            value=repr(self.value)
        )
 
    def __repr__(self):
        return self.__str__()
 
class Interpreter(object):
    def __init__(self, text):
        self.__text = text
        self.__pos = 0
        self.__current_token = None
 
    def error(self):
        raise Exception('Error parsing input')
 
    def get_next_token(self):
        """Lexical analyzer (also known as scanner or tokenizer)
 
        This method is responsible for breaking a sentence
        apart into tokens. One token at a time.
        """
        text = self.__text
 
        if self.__pos > len(text) - 1:
            return Token(EOF, None)
 
        current_char = text[self.__pos]
 
        if current_char.isdigit():
            token = Token(INTEGER, int(current_char))
            self.__pos += 1
            return token
 
        if current_char == '+':
            token = Token(PLUS, current_char)
            self.__pos += 1
            return token
 
        self.error()
 
    def eat(self, token_type):
        if self.__current_token.type == token_type:
            self.__current_token = self.get_next_token()
        else:
            self.error()
 
    def expr(self):
        """expr -> INTEGER PLUS INTEGER"""
        self.__current_token = self.get_next_token()
 
        left = self.__current_token
        self.eat(INTEGER)
 
        op = self.__current_token
        self.eat(PLUS)
 
        right = self.__current_token
        self.eat(INTEGER)
        result = left.value + right.value
        return result
 
def main():
    while True:
        try:
            text = input('calc> ')
        except EOFError:
            break
        if not text:
            continue
        interpreter = Interpreter(text)
        result = interpreter.expr()
        print(result)
 
if __name__ == '__main__':
    main()
